from collections import defaultdict

from build_feature.extract_npm_different_version_functions.core.function_diff_info import FunctionDifferenceType
from build_feature.extract_npm_different_version_functions.core.function_info import FunctionInfo



def conversion_data(git_repository, modified_functions):
    # 版本修改信息和函数信息生成
    version_diff_function_mate_info = defaultdict(dict)
    diff_function_info = []
    diff_function_unique_key_set = set()
    all_version_name_list = []
    for version_pair, version_diff_info_list in modified_functions.items():
        version_list = version_pair.split("@")
        from_version = version_list[0]
        to_version = version_list[1]
        # 实际提取版本列表
        if len(all_version_name_list) == 0 or all_version_name_list[-1] != from_version:
            all_version_name_list.append(from_version)
        all_version_name_list.append(to_version)
        from_version_index = len(all_version_name_list) - 2
        to_version_index = len(all_version_name_list) - 1
        for function_diff_info in version_diff_info_list:
            if len(version_diff_function_mate_info[to_version]) == 0:
                version_diff_function_mate_info[to_version]["from_version"] = from_version
                version_diff_function_mate_info[to_version]["diff_function"] = []
            diff_type = function_diff_info.get_diff_type()
            if diff_type == FunctionDifferenceType.ADD:
                # 新增函数
                add_function = function_diff_info.get_to_function_info()
                add_function_unique_key = FunctionInfo.generate_unique_key(add_function)
                version_diff_function_mate_info[to_version]["diff_function"].append(
                    {"function_key": add_function_unique_key, "type": "add"})
                if add_function_unique_key not in diff_function_unique_key_set:
                    add_function_src = add_function.get_src_info()
                    add_function_src["unique_key"] = add_function_unique_key
                    add_function_src["version_start_index"] = [to_version_index]
                    add_function_src["version_end_index"] = []
                    diff_function_info.append(add_function_src)
                    # key 加入集合
                    diff_function_unique_key_set.add(add_function_unique_key)
                else:
                    function_info_src = get_function_src_info_by_unique_key(add_function_unique_key, diff_function_info)
                    if len(function_info_src["version_start_index"]) == len(function_info_src["version_end_index"]):
                        # 函数开始版本索引和结束版本索引对完整
                        function_info_src["version_start_index"].append(to_version_index)
            elif diff_type == FunctionDifferenceType.DELETE:
                # 删除函数
                delete_function = function_diff_info.get_from_function_info()
                delete_function_unique_key = FunctionInfo.generate_unique_key(delete_function)
                version_diff_function_mate_info[to_version]["diff_function"].append(
                    {"function_key": delete_function_unique_key, "type": "delete"})
                # 函数详细信息没被添加
                if delete_function_unique_key not in diff_function_unique_key_set:
                    delete_function_src = delete_function.get_src_info()
                    delete_function_src["unique_key"] = delete_function_unique_key
                    # 函数没有在以前版本被修改或添加，断定函数来自第一个版本
                    delete_function_src["version_start_index"] = [0]
                    delete_function_src["version_end_index"] = [from_version_index]
                    diff_function_info.append(delete_function_src)
                else:
                    function_info_src = get_function_src_info_by_unique_key(delete_function_unique_key, diff_function_info)
                    if len(function_info_src["version_start_index"]) == len(function_info_src["version_end_index"]):
                        # 函数开始版本索引和结束版本索引对完整
                        function_info_src["version_start_index"].append(from_version_index)
                    function_info_src["version_end_index"].append(from_version_index)
            elif diff_type == FunctionDifferenceType.UPDATE:
                # 修改函数
                from_function_info = function_diff_info.get_from_function_info()
                to_function_info = function_diff_info.get_to_function_info()
                from_function_unique_key = FunctionInfo.generate_unique_key(from_function_info)
                to_function_unique_key = FunctionInfo.generate_unique_key(to_function_info)
                version_diff_function_mate_info[to_version]["diff_function"].append(
                    {"from_function_key": from_function_unique_key, "function_key": to_function_unique_key,
                     "type": "update"})
                if from_function_unique_key not in diff_function_unique_key_set:
                    from_function_src = from_function_info.get_src_info()
                    from_function_src["unique_key"] = from_function_unique_key
                    # 函数没有在以前版本被修改或添加，断定函数来自第一个版本
                    from_function_src["version_start_index"] = [0]
                    from_function_src["version_end_index"] = [from_version_index]
                    diff_function_info.append(from_function_src)
                else:
                    function_info_src = get_function_src_info_by_unique_key(from_function_unique_key, diff_function_info)
                    if len(function_info_src["version_start_index"]) == len(function_info_src["version_end_index"]):
                        # 函数开始版本索引和结束版本索引对完整
                        function_info_src["version_start_index"].append(from_version_index)
                    function_info_src["version_end_index"].append(from_version_index)
                if to_function_unique_key not in diff_function_unique_key_set:
                    to_function_src = to_function_info.get_src_info()
                    to_function_src["unique_key"] = to_function_unique_key
                    to_function_src["version_start_index"] = [to_version_index]
                    to_function_src["version_end_index"] = []
                    diff_function_info.append(to_function_src)
                    # key 加入集合
                    diff_function_unique_key_set.add(to_function_unique_key)
                else:
                    function_info_src = get_function_src_info_by_unique_key(to_function_unique_key, diff_function_info)
                    if len(function_info_src["version_start_index"]) == len(function_info_src["version_end_index"]):
                        # 函数开始版本索引和结束版本索引对完整
                        function_info_src["version_start_index"].append(to_version_index)

    for function_info_src in diff_function_info:
        if len(function_info_src["version_start_index"]) != len(function_info_src["version_end_index"]):
            function_info_src["version_end_index"].append(len(all_version_name_list) - 1)
        version_start_index_list = function_info_src["version_start_index"]
        version_end_index_list = function_info_src["version_end_index"]
        function_info_src["version"] = []
        for index in range(len(function_info_src["version_start_index"])):
            version_start_index = version_start_index_list[index]
            version_end_index = version_end_index_list[index] + 1
            src_version_list = all_version_name_list[version_start_index: version_end_index]
            function_info_src["version"].extend(src_version_list)
    # 版本信息生成
    version_mate_info = {}
    version_mate_info["library"] = git_repository.path_base_name
    version_mate_info["totalVersionNum"] = len(all_version_name_list)
    version_mate_info["versionInfo"] = []
    tag_list = git_repository.get_tags()
    tag_index = 0
    for version_name in all_version_name_list:
        while tag_index < len(tag_list):
            if tag_list[tag_index].name == version_name:
                version_mate_info["versionInfo"].append({
                    "version": tag_list[tag_index].name,
                    "dataTime": tag_list[tag_index].commit.committed_datetime.strftime("%Y-%m-%d %H:%M:%S"),
                })
                tag_index += 1
                break
            tag_index += 1
    return version_mate_info, version_diff_function_mate_info, diff_function_info




def get_function_src_info_by_unique_key(unique_key, function_info_src_list):
    for function_info in function_info_src_list:
        if function_info["unique_key"] == unique_key:
            return function_info
    return None
def converion_history(history_no_diff_functions):
    """将 history_no_diff_functions 转换为包含额外信息的字典列表"""
    history_no_diff_functions_mate_info = []

    # 检查 history_no_diff_functions 是否为 None 或空
    if history_no_diff_functions is not None:
        for history_no_diff_function in history_no_diff_functions:
            # 获取函数的源信息
            history_object = history_no_diff_function.get_src_info()
            # 生成唯一的 key
            history_object["unique_key"] = FunctionInfo.generate_unique_key(history_no_diff_function)
            # 将转换后的对象添加到结果列表中
            history_no_diff_functions_mate_info.append(history_object)

    return history_no_diff_functions_mate_info


def generate_version_in_function_diff_info(version_meta_info, version_diff_function_meta_info, diff_function_info):
    all_version_name_list = []
    for version_info in version_meta_info["versionInfo"]:
        all_version_name_list.append(version_info["version"])
    diff_function_info_dict = {}
    for function_info_src in diff_function_info:
        function_info_src["version_start_index"] = []
        function_info_src["version_end_index"] = []
        function_info_src["version"] = []
        diff_function_info_dict[function_info_src["unique_key"]] = function_info_src
    for index in range(len(all_version_name_list)):
        diff_function_meta_info_dict =  version_diff_function_meta_info.get(all_version_name_list[index], {})
        if len(diff_function_meta_info_dict) == 0:
            continue
        from_version_index = all_version_name_list.index(diff_function_meta_info_dict["from_version"])
        for diff_function_meta_info in diff_function_meta_info_dict["diff_function"]:
            if diff_function_meta_info["type"] == "add":
                function_info_src = diff_function_info_dict[diff_function_meta_info["function_key"]]
                if len(function_info_src["version_start_index"]) == len(function_info_src["version_end_index"]):
                    # 函数开始版本索引和结束版本索引对完整
                    function_info_src["version_start_index"].append(index)
            elif diff_function_meta_info["type"] == "delete":
                function_info_src = diff_function_info_dict[diff_function_meta_info["function_key"]]
                if len(function_info_src["version_start_index"]) == 0:
                    function_info_src["version_start_index"].append(0)
                if len(function_info_src["version_start_index"]) == len(function_info_src["version_end_index"]):
                    # 函数开始版本索引和结束版本索引对完整
                    function_info_src["version_start_index"].append(from_version_index)
                function_info_src["version_end_index"].append(from_version_index)
            elif diff_function_meta_info["type"] == "update":
                from_function_info = diff_function_info_dict[diff_function_meta_info["from_function_key"]]
                if len(from_function_info["version_start_index"]) == 0:
                    from_function_info["version_start_index"].append(0)
                if len(from_function_info["version_start_index"]) == len(from_function_info["version_end_index"]):
                    # 函数开始版本索引和结束版本索引对完整
                    from_function_info["version_start_index"].append(from_version_index)
                from_function_info["version_end_index"].append(from_version_index)
                to_function_info = diff_function_info_dict[diff_function_meta_info["function_key"]]
                if len(to_function_info["version_start_index"]) == len(to_function_info["version_end_index"]):
                    # 函数开始版本索引和结束版本索引对完整
                    to_function_info["version_start_index"].append(index)
    for function_info_src in diff_function_info:
        if len(function_info_src["version_start_index"]) != len(function_info_src["version_end_index"]):
            function_info_src["version_end_index"].append(len(all_version_name_list) - 1)
        version_start_index_list = function_info_src["version_start_index"]
        version_end_index_list = function_info_src["version_end_index"]
        for index in range(len(function_info_src["version_start_index"])):
            version_start_index = version_start_index_list[index]
            version_end_index = version_end_index_list[index] + 1
            src_version_list = all_version_name_list[version_start_index: version_end_index]
            function_info_src["version"].extend(src_version_list)